package com.xgk.boot.module.infra.service.file;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.google.common.cache.Cache;
import com.xgk.boot.framework.common.util.cache.CacheUtils;
import com.xgk.boot.module.infra.dal.dataobject.config.ConfigDO;
import com.xgk.boot.module.infra.enums.cache.CacheConstants;
import com.xgk.boot.module.infra.service.config.ConfigService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.io.File;
import java.nio.file.FileAlreadyExistsException;
import java.time.Duration;

@Slf4j
@Service
public class LocalFileService {

    @Resource
    private ConfigService configService;

    @Autowired
    @Lazy  // 避免循环依赖问题
    private LocalFileService self;  // 注入自身

    //缓存，避免重复创建
    private static Cache<String,String> creatDirCache =  CacheUtils.buildCache(Duration.ofHours(3));

    @Cacheable(cacheNames = CacheConstants.LOCAL_FILE_CONFIG, key = "#dirKey")
    public String getFileDir(String dirKey){
        ConfigDO configByKey = configService.getConfigByKey(dirKey);
        if(configByKey ==null){
            log.warn("Cannot  find config:[{}]",dirKey);
            return null;
        }
        return configByKey.getValue();
    }

    public String getTempDir(){
//        String fileDir = "./temp";
        String fileDir = self.getFileDir(FileConstant.TEMP_FILE_DIR);
        if(fileDir ==null){
            fileDir = "./temp";
        }
        String currentMonth = DateUtil.format(DateUtil.date(), "yyyyMM");
        File file = FileUtil.file(fileDir, currentMonth,"/");
        ensureDir(file);
        if(isLastDayOfMonth()){
            DateTime dateTime = DateUtil.endOfMonth(DateUtil.date());
            String lastMonth = DateUtil.format(dateTime, "yyyyMM");
            String cacheName = "temp-"+lastMonth;
            if(creatDirCache.getIfPresent(cacheName) ==null){
                creatNextDir(fileDir,lastMonth);
                creatDirCache.put(cacheName,lastMonth);
            }
        }
        return file.getAbsolutePath();
    }

    public String getLocalFileDir(){
        String fileDir = self.getFileDir(FileConstant.LOCAL_FILE_DIR);
        if(fileDir ==null){
            fileDir = "./file";
        }
        String currentMonthDay = DateUtil.format(DateUtil.date(), "yyyyMMdd");
        File file = FileUtil.file(fileDir, currentMonthDay,"/");
        ensureDir(file);
        if(isLastDayOfMonth()){
            DateTime dateTime = DateUtil.endOfMonth(DateUtil.date());
            String lastMonthDay = DateUtil.format(dateTime, "yyyyMMdd");
            String cacheName = "file-"+lastMonthDay;
            if(creatDirCache.getIfPresent(cacheName) ==null){
                creatNextDir(fileDir,lastMonthDay);
                creatDirCache.put(cacheName,lastMonthDay);
            }
        }
        return file.getAbsolutePath();
    }

     /**
             * 确保目录存在（不存在则创建）
     * @return 目录File对象
     * @throws IllegalArgumentException 如果路径为空
     * @throws FileAlreadyExistsException 如果路径已存在但不是目录
     * @throws RuntimeException 如果目录创建失败
     */
    public static File ensureDir(File file) {
        // 如果目录已存在
        if (file.exists()) {
            if (!file.isDirectory()) {
                throw new RuntimeException("Path exists but is not a directory: " + file.getAbsolutePath());
            }
            return file;
        }
        // 创建目录（包含所有不存在的父目录）
        return FileUtil.mkdir(file);
    }

    /**
     * 判断指定日期是否为当月最后一天
     * @return 是否为当月最后一天
     */
    public  boolean isLastDayOfMonth() {
        DateTime today = DateUtil.date();
        DateTime lastDay = DateUtil.endOfMonth(today);
        return DateUtil.isSameDay(today, lastDay);
    }

    private synchronized void creatNextDir(String path,String pathEnd){
        try {
            File file = FileUtil.file(path, pathEnd,"/");
            ensureDir(file);
        }catch (Throwable e){
            log.error(String.format("creat dir:[{}] , [{}] error",path,pathEnd),e);
        }
    }

    public static void main(String[] args) {
        LocalFileService fileService = new LocalFileService();
        System.out.println(fileService.getTempDir());
    }



}
